<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../js/vue.global.js"></script>
</head>

<body>
    <div id="app">
        <p>count:{{count}}---{{doubleCount}}</p>
        <p>
            <button @click="addCount">count++</button>
            <button @click="doubleCount+=2">doubleCount+2</button>
        </p>
        <hr>
        <p>
            {{zhang.name}}----{{zhang.age}}----{{zhang.info.height}}----{{zhang.info.weight}}
        </p>
        <p>
            <button @click="changeName">changeName</button>
            <button @click="changeAge">changeAge</button>
            <button @click="changeHeight">changeHeight</button>
        </p>
    </div>
</body>
<script>

    // 组合式 API 的核心思想是直接在函数作用域内定义响应式状态变量，并将从多个函数中得到的状态组合起来处理复杂问题

    let { createApp } = Vue;
    let { ref, reactive, readonly, computed, watch,watchEffect } = Vue;


    let app = createApp({
        setup(props) {

            // ref
            var count = ref(10); // {value:10}
            // console.log("count", count);

            // reactive (响应式代理)
            var zhang = reactive({ name: "张三", age: 18, info: { height: 177, weight: 70 } });
            // console.log("zhang", zhang);

            // 计算属性
            let doubleCount = computed({
                get: () => {
                    return count.value * 2;
                },
                set: (val) => {
                    count.value  = val /  2;
                }
            })
            // console.log("doubleCount", doubleCount);


            // methods
            let addCount = () => {
                count.value++;
            }


            let changeName = () => {
                zhang.name = "李四"
            }

            let changeAge = () => {
                zhang.age++
            }

            let changeHeight = () => {
                zhang.info.height++
            }



            // watchEffect(callback,options)  立即运行一个函数，同时响应式地追踪其依赖，并在依赖更改时重新执行。
            // callback  回调函数
            // options   可选的参数 => 一个对象
            //       flush?: 'pre' | 'post' | 'sync'
     
            // 1.  watchEffect中接受的回调函数，会在初始化阶段立即执行一次
            // 2.  回调函数使用的数据(ref reactive computed), 默认会成为watchEffect的响应式依赖, 并在依赖更改时重新执行。


            // 对比计算属性
            // 1. 公共点:
            //   a. 会在初始化阶段立即执行一次

            // 2. 不同点
            //   计算属性要求返回新值, watchEffect会在响应式依赖更改时重新执行。

            // 对比watch数据监听
            // 1. 公共点:
            //    a.检测数据改变,并在数据改变之后执行一系列副作用操作

            // 2. 不同点:
            //    a. watch监听数据时默认是惰性的, 等数据改变后再执行,  watchEffect会在初始化阶段立即执行一次
            //    b. watch监听数据时,可以知道改变的newVal,oldVal, watchEffect只关注依赖的数据是否改变,不管新值和旧值


            // 商品搜索
            /* 
            data:{
                searchParams:{
                    search:"",
                    category:""
                }
            },
            methods:{ 
                getData(){}
            },
            watch:{
                searchParams:{
                    handler:function(){
                         this.getDate();
                    },
                    deep:true,
                }
            }
            mounted(){
                this.getDate();
            } 
            */

            watchEffect(()=>{
                console.log("watchEffect中的函数执行了");

                console.log("count",count.value);
                console.log("doubleCount",doubleCount.value);
                console.log("zhang",zhang.age);

            })
             


            return {
                count,
                doubleCount,
                addCount,
                zhang,
                changeName,
                changeAge,
                changeHeight,
            }
        },
        mounted() {
            // console.log("代理对象this", this);

            /*  new Proxy({},{
                 get(){
                     // 判断是否是ref对象  => ref.value
                 },
                 set(){
                     // 判断是否是ref对象   => ref.value = xxx
                 }
             }) */
        },
    })


    app.mount("#app");


</script>

</html>